﻿/*code is far away from bug with the animal protecting
*  ┏┓　　　┏┓
*┏┛┻━━━┛┻┓
*┃　　　　　　　┃ 　
*┃　　　━　　　┃
*┃　┳┛　┗┳　┃
*┃　　　　　　　┃
*┃　　　┻　　　┃
*┃　　　　　　　┃
*┗━┓　　　┏━┛
*　　┃　　　┃
*　　┃　　　┃
*　　┃　　　┗━━━┓
*　　┃　神兽保佑　　┣┓
*　　┃　代码无BUG！ ┏┛
*　　┗┓┓┏━┳┓┏┛
*　　　┃┫┫　┃┫┫
*　　　┗┻┛　┗┻┛ 
*　　　
*/

using AutoMapper;
using Controllers.DTO;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using Middleware;
using Model;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;

namespace Controllers
{
    [ApiController]//这里是api
    [Route("[controller]")]//api路由规则
    public class AccountController : ControllerBase
    {
        private readonly DBHelper _dB;
        private readonly AuthOptions _options;
        private readonly IMapper _mapper;
        public AccountController(DBHelper db, IMapper mapper, IOptions<AuthOptions> options)
        {
            _dB = db;
            _options = options.Value;
            _mapper = mapper;
        }
        /// <summary>
        /// 登陆
        /// </summary>
        /// <param name="username">用户</param>
        /// <param name="password">密码</param>
        /// <returns></returns>
        [HttpPost("Login")]
        public ReturnUser Login([FromBody]LoginInput input)
        {
            ReturnUser user = new ReturnUser() { Id = 0 };
            var _user = _dB.GetList<Users>("select * from Users where UserName='" + input.username + "'").FirstOrDefault();
            if (_user != null)
            {
                if (_user.Password == input.password.EncryPassword(_user.PrimaryKey))
                {
                    user.Id = _user.Id;
                    user.Role = _mapper.Map<RoleDto>(_dB.GetList<Role>("select * from Role where id=" + _user.RoleId).FirstOrDefault());
                    user.ImageUrl = _user.ImageUrl;
                    user.RealName = _user.RealName;
                    user.Name = _user.UserName;
                    var dt = DateTime.UtcNow;
                    var issuer = _options.Issuer;
                    var audience = _options.Audience;
                    var concurrencyStamp = Guid.NewGuid().ToString("N");
                    var claims = new Claim[]
                    {
                        new Claim(ClaimTypes.Name,user.Id.ToString(),ClaimValueTypes.Integer64),
                        new Claim(JwtRegisteredClaimNames.Jti,concurrencyStamp),
                        new Claim(JwtRegisteredClaimNames.Iat,Guid.NewGuid().ToString("N")),
                        new Claim("UserId",user.Id.ToString(),ClaimValueTypes.Integer64),
                        new Claim("RealName",user.RealName),
                        new Claim("RoleId",_user.RoleId.ToString()),
                        new Claim("UserName",user.Name),
                    };
                    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_options.Secret));
                    var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
                    var token = new JwtSecurityToken(
                        issuer: issuer,
                        audience: audience,
                        claims: claims,
                        notBefore: dt,
                        expires: dt.AddDays(_options.ExpiryHour),
                        signingCredentials: creds);
                    user.Token = new JwtSecurityTokenHandler().WriteToken(token);
                    user.ExpireTime = DateTime.Now.AddHours(_options.ExpiryHour);
                }
            }
            return user;
        }
        /// <summary>
        /// 重置密码
        /// </summary>
        /// <param name="username">用户</param>
        /// <param name="newpassword">新密码</param>
        /// <param name="oldpassword">旧密码</param>
        /// <returns></returns>        
        [HttpPut("Reset")]
        public bool ResetPassword(string username, string oldpassword, string newpassword)
        {
            var _user = _dB.GetList<Users>("select * from Users where UserName='" + username + "'").FirstOrDefault();
            if (_user != null)
            {
                if (_user.Password == oldpassword.EncryPassword(_user.PrimaryKey))
                {
                    _user.Password = newpassword.EncryPassword(_user.PrimaryKey);
                    return _dB.ExcuteEntity(_user, SqlOperate.Update, this.HttpContext);
                }
            }
            return false;
        }
    }
}
